package com.pc.cloud.services;

import com.pc.cloud.utils.NamePair;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.*;
import java.util.Map.Entry;


public class SearchResults {
	private int total; //total number
	private List<String> lists = new ArrayList<String>(); //current page result
	
	//obtainValue
	private List<String> valueLists = new ArrayList<String>();
	

	//facet search
	private Map<String,List<NamePair>> facets = new HashMap<String,List<NamePair>>(); //facet search
	
	//summary
	private Collection<NamePair> sum;
	private Map<String,Collection<FacetSearchRow>> sumFacets = new HashMap<String,Collection<FacetSearchRow>>();
			
	
	public List<String> getValueLists() {
		return valueLists;
	}
	public void setValueLists(List<String> valueLists) {
		this.valueLists = valueLists;
	}
	
	
	public Map<String, List<NamePair>> getFacets() {
		return facets;
	}
	public void setFacets(Map<String, List<NamePair>> facets) {
		this.facets = facets;
	}
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}
	public List<String> getLists() {
		return lists;
	}
	public void setLists(List<String> lists) {
		this.lists = lists;
	}
	
	public static SearchResults getFromJson(String json) throws Exception {		
		SearchResults sr = new SearchResults();
		JSONObject result = new JSONObject(json);
		int total = result.getInt("total");
		sr.setTotal(total);
		
		JSONArray lists = result.getJSONArray("lists");
		List<String> ids = new ArrayList<String>();
		if(lists != null) {
			for(int i=0; i<lists.length(); i++) {
				String id = lists.getString(i);
				ids.add(id);
			}
		}
		sr.setLists(ids);
				
		try {
			JSONArray jvls = result.optJSONArray("valueLists");
			
			if(jvls != null && jvls.length()>0) {
				List<String> values = new ArrayList<String>();
				for(int i=0; i<jvls.length(); i++) {
					String v = jvls.getString(i);
					values.add(v);
				}
				
				sr.setValueLists(values);
			}
		}catch(Exception e) {}
		
		
		JSONArray fs = result.getJSONArray("facets");		
		if(fs != null) {
			Map<String,List<NamePair>> facets = jsonToFacets(fs);			
			sr.setFacets(facets);
		}
		
		try {
			JSONArray sja = result.getJSONArray("sum");
			if(sja != null && sja.length() >0) {
				List<NamePair> pairs = new ArrayList<NamePair>();
				for(int j=0; j<sja.length(); j++) {
					JSONObject pair = sja.getJSONObject(j);
					NamePair namePair = new NamePair(pair.getString("name"),pair.getString("value"));
					pairs.add(namePair);
				}
				
				sr.setSum(pairs);
			}
		}catch(Exception e){}
		
		try {
			JSONArray sfja = result.getJSONArray("sumFacets");
			if(sfja != null && sfja.length()>0) {
				Map<String,Collection<FacetSearchRow>> sumFacets = jsonToFacetSums(sfja);
				sr.setSumFacets(sumFacets);
			}
		}catch(Exception e){}
		
		return sr;
	}
	
	private static Map<String, Collection<FacetSearchRow>> jsonToFacetSums(JSONArray sfja) throws Exception {
		Map<String,Collection<FacetSearchRow>> facets = new HashMap<String,Collection<FacetSearchRow>>();
		for(int i=0; i<sfja.length(); i++) {
			JSONObject facet = sfja.getJSONObject(i);
			//Map<Object,Object> map = facet.getObjectMap();
			Iterator<String> iterator = (Iterator<String>)facet.keys();
			while(iterator.hasNext()){
				String field = iterator.next();
				JSONArray ps = facet.getJSONArray(field);
				List<FacetSearchRow> rows = new ArrayList<FacetSearchRow>();
				for(int j=0; j<ps.length(); j++) {
					JSONObject jr = ps.getJSONObject(j);
					FacetSearchRow fsr = new FacetSearchRow();
					fsr.setName(jr.getString("name"));
					fsr.setTotal(jr.optInt("total"));
					JSONArray jps = jr.getJSONArray("pairs");
					List<NamePair> pairs = new ArrayList<NamePair>();
					for(int h=0;h<jps.length();h++) {
						JSONObject pair = jps.getJSONObject(h);
						NamePair namePair = new NamePair(pair.getString("name"),pair.getString("value"));
						pairs.add(namePair);
					}
					fsr.setPairs(pairs);
					
					rows.add(fsr);
				}
				facets.put(field, rows);
			}
		
		}
		return facets;
	}
	private static Map<String, List<NamePair>> jsonToFacets(JSONArray fs) throws Exception {
		Map<String,List<NamePair>> facets = new HashMap<String,List<NamePair>>(); 
		for(int i=0; i<fs.length(); i++) {
			JSONObject facet = fs.getJSONObject(i);
			//Map<Object,Object> map = facet.getObjectMap();
			Iterator<String> iterator = (Iterator<String>)facet.keys();
			while(iterator.hasNext()){
				String field = iterator.next();
				JSONArray ps = facet.getJSONArray(field);
				List<NamePair> pairs = new ArrayList<NamePair>();
				for(int j=0; j<ps.length(); j++) {
					JSONObject pair = ps.getJSONObject(j);
					NamePair namePair = new NamePair(pair.getString("name"),pair.getString("value"));
					pairs.add(namePair);
				}
				facets.put(field, pairs);
			}
		}
		return facets;
	}
	public String toJSON() throws Exception {
		JSONObject result = new JSONObject();
		result.put("total", this.getTotal());
		JSONArray lists = new JSONArray();
		for(String id : this.getLists()) {
			lists.put(id);
		}
		result.put("lists", lists);
		
		if(this.valueLists != null && this.valueLists.size()>0) {
			JSONArray valueLists = new JSONArray();
			for(String value : this.getValueLists()) {
				valueLists.put(value);
			}			
			result.put("valueLists", valueLists);
		}
		
		JSONArray facets = getFacetJSON(this.getFacets());		
		result.put("facets", facets);
		
		if(this.sum != null && this.sum.size()>0) {
			JSONArray sja = new JSONArray();			
			for(NamePair pair : this.sum) {
				JSONObject p = new JSONObject();
				p.put("name", pair.getName());
				p.put("value", pair.getValue());
				sja.put(p);				
			}					
			result.put("sum", sja);
		}
		
		if(this.sumFacets!=null && this.sumFacets.size()>0) {
			JSONArray sfja = this.getFacetSumJSON(this.sumFacets);
			result.put("sumFacets", sfja);
		}
		
		return result.toString();
	}
	private JSONArray getFacetSumJSON(Map<String, Collection<FacetSearchRow>> sumFacets) throws Exception {
		JSONArray facets = new JSONArray();
		for(Entry<String,Collection<FacetSearchRow>> entry : sumFacets.entrySet()){
			String field = entry.getKey();
			Collection<FacetSearchRow> rows = entry.getValue();
			JSONArray rs = new JSONArray();
			for(FacetSearchRow row : rows) {
				JSONObject r = new JSONObject();
				r.put("name", row.getName());	
				r.put("total", row.getTotal());
				JSONArray pairs = new JSONArray();
				for(NamePair pair : row.getPairs()) {
					JSONObject p = new JSONObject();
					p.put("name", pair.getName());
					p.put("value", pair.getValue());
					pairs.put(p);				
				}			
				r.put("pairs", pairs);
				rs.put(r);				
			}
			JSONObject facet = new JSONObject();
			facet.put(field,rs);
			facets.put(facet);
		}
		return facets;
	}
	private JSONArray getFacetJSON(Map<String, List<NamePair>> facets2) throws Exception {
		JSONArray facets = new JSONArray();
		for(Entry<String,List<NamePair>> entry : facets2.entrySet()){
			String field = entry.getKey();
			List<NamePair> pairs = entry.getValue();
			JSONArray ps = new JSONArray();
			for(NamePair pair : pairs) {
				JSONObject p = new JSONObject();
				p.put("name", pair.getName());
				p.put("value", pair.getValue());
				ps.put(p);				
			}
			JSONObject facet = new JSONObject();
			facet.put(field,ps);
			facets.put(facet);
		}
		return facets;
	}
	public Collection<NamePair> getSum() {
		return sum;
	}
	public void setSum(Collection<NamePair> sum) {
		this.sum = sum;
	}
	public Map<String, Collection<FacetSearchRow>> getSumFacets() {
		return sumFacets;
	}
	public void setSumFacets(Map<String, Collection<FacetSearchRow>> sumFacets) {
		this.sumFacets = sumFacets;
	}
}